// Term.cpp : implementation file
//

#include "stdafx.h"
#include "Term.h"



bool Term::isReducible() const{
	return getType().isReducible();
	}
string Term::view() const{
	return string("Te")+Token::view()+string(":")+m_Type->view();
	}
bool Term::operator==(Token::const_reference To){
	if(To.isTerm()){
		return(((_TERM(To)).getType()==getType())&&(Token::operator ==(To)));
		}
	return false;
}
Token::pointer Term::replaceAll(Token::const_reference Occurences, Token::const_reference byTheGuyHere) const{			
	if((Occurences.isType())&&(byTheGuyHere.isType())){
		Term::pointer Ter=static_cast<Term::pointer>(clone());
		Type::pointer NewType = static_cast<Type::pointer>
												(this->getType().replaceAll(Occurences,byTheGuyHere));
		Ter->assignType(*NewType);
		delete NewType;
		return Ter;
		}
	if((Occurences.isTerm())&&(byTheGuyHere.isTerm())){
		return Token::replaceAll(Occurences, byTheGuyHere);
		}
	throw TermXception("Illegal Replacement Operation attempted at Term::replaceAll()"); 
};
 COUNTER Term::complexity() const{
	 return Token::complexity() + getType().complexity();
	 }

void Term::normalizeType(){
	Token::pointer NewType = m_Type->normalized();
	this->assignType(_TYPE(*NewType));
	delete  NewType;
}



void Term::setTypeSyntax(string ss){
	this->m_Type->setSyntax(ss);
};

Term::Term(const Type& Ty, const string& ss):
Token(ss), m_Type((Type*)0){
	this->assignType(Ty); 	
}

Term::Term(Term::const_reference Ter):
Token(Ter),m_Type(NULL)
{	
	this->assignType(Ter.getType());
}

Term::~Term(){
	if(this->m_Type){
		delete this->m_Type;
		m_Type=(Type*)0;
		}
}

void Term::assignType(Type::const_reference Ty){
	if(this->m_Type)
		delete this->m_Type;
	this->m_Type = (Type*)0;
	this->m_Type=static_cast<Type::pointer>(Ty.clone());
}

Type::pointer Term::ResolveType(Type::const_reference TL, Type::const_reference TR){
	if(TL.isAbstractType())           
		return  static_cast<Type::pointer>(TL.applyArgument(TR));
             
	if(TL.isArrowType())
		if(_ARROWTYPE(TL).getLeft() == TR)
			return static_cast<Type::pointer>(_ARROWTYPE(TL).getRight().clone());
	
  
    throw Term::exception("Unable to resolve ApplicationTerm Type at Term::ResolveType(Token::const_reference, Token::const_reference)");
}





